/* fppShLib.h - SH Version of Floating-Point Include File */

/* Copyright (c) 1994-2005 Wind River Systems, Inc. */
/*
modification history
--------------------
01n,09mar05,asa  added typedef UNIOND64 and moved constants HREG and LREG
                 from fppArchShow for use in fppArchShow and fppArchMRegs
                 moved extern function definitions to usrCoprocSh.c
                 updated copyright to 2005
                 removed if def(__STDC__) || def(__cplusplus) false branch
01m,02dec04,h_k  changed fpx size to int. (SPR #104932)
01l,14oct04,h_k  align 64 bit for FP_CONTEXT. (SPR #102473)
                 removed SH7718(SH3e) support and CPU type conditions.
                 added externs for PAL coprocessor abstraction.
01k,05dec02,hk   moved _WRS_HW_FP_SUPPORT from fppShLib.h to archSh.h(SPR#83145)
01j,12sep01,zl   added definition of _WRS_HW_FP_SUPPORT.
01i,02oct00,zl   moved FPSCR_INIT out of _ASMLANGUAGE conditional.
01h,13jul00,hk   made fppRegGet/fppRegSet func prototypes for SH7750 only.
01g,29jun00,hk   added FPSCR bit definition. changed FPSCR_INIT for SH7700.
		 updated function declarations.
01f,28jun00,zl   addded FPSCR default value.
01e,20mar00,zl   added extended floating point registers to the FP context
01d,20may98,hk   added fppProbeSup() and fppProbeTrap() prototypes.
01c,26nov97,hms  delete definition of fppProbeSup().
01b,25nov97,st   added FPU registers.
01a,09oct94,hk   written - derived from sparc 02j.
*/

#ifndef __INCfppShLibh
#define __INCfppShLibh

#ifdef __cplusplus
extern "C" {
#endif

#include "vxWorks.h"
#include "reg.h"
#include "esf.h"


/* FP_CONTEXT structure offsets */

#define FPUL		0x00		/* OFFSET(FP_CONTEXT, fpul)	*/
#define FPSCR		0x04		/* OFFSET(FP_CONTEXT, fpscr)	*/
#define FPX		0x08		/* OFFSET(FP_CONTEXT, fpr[0])	*/
#define FPX_OFFSET(n)	(FPX + (n)*4)	/* OFFSET(FP_CONTEXT, fpr[n])	*/


/* FPSCR (Floating Point Status/Control Register) bit definition */

#define FPSCR_BANK1_SELECT		0x00200000
#define FPSCR_FMOV_32BIT_PAIR		0x00100000
#define FPSCR_DOUBLE_PRECISION		0x00080000
#define FPSCR_DENORM_TRUNCATE		0x00040000

#define FPSCR_CAUSE_FPU_ERROR		0x00020000
#define FPSCR_CAUSE_INVALID_OP		0x00010000
#define FPSCR_CAUSE_ZERO_DIVIDE		0x00008000
#define FPSCR_CAUSE_OVERFLOW		0x00004000
#define FPSCR_CAUSE_UNDERFLOW		0x00002000
#define FPSCR_CAUSE_INEXACT		0x00001000

#define FPSCR_ENABLE_INVALID_OP		0x00000800
#define FPSCR_ENABLE_ZERO_DIVIDE	0x00000400
#define FPSCR_ENABLE_OVERFLOW		0x00000200
#define FPSCR_ENABLE_UNDERFLOW		0x00000100
#define FPSCR_ENABLE_INEXACT		0x00000080

#define FPSCR_FLAG_INVALID_OP		0x00000040
#define FPSCR_FLAG_ZERO_DIVIDE		0x00000020
#define FPSCR_FLAG_OVERFLOW		0x00000010
#define FPSCR_FLAG_UNDERFLOW		0x00000008
#define FPSCR_FLAG_INEXACT		0x00000004

#define FPSCR_ROUND_MODE_MASK		0x00000003
#define FPSCR_ROUND_TO_ZERO		0x00000001
#define FPSCR_ROUND_TO_NEAREST		0x00000000

#define FP_NUM_DREGS	32
#define FPSCR_INIT	FPSCR_DOUBLE_PRECISION			/* FPSCR_PR */
#define FPSCR_SZ_PR	(FPSCR_INIT | FPSCR_FMOV_32BIT_PAIR)	/* FPSCR_SZ_PR*/
#define _FP_ALIGN_SIZE	8					/* 64 bit */

#ifndef _ASMLANGUAGE

typedef struct fpContext                /* Floating-Point Context        */
    {
    int		fpul;			/* FPU communication reg. :   4  */
    int		fpscr;			/* FPU status/control reg.:   4  */
    int		fpx[FP_NUM_DREGS];	/* FPU registers	  : 128  */
					/* TOTAL		  : 136  */
    } WRS_PACK_ALIGN(_FP_ALIGN_SIZE) FP_CONTEXT;

#define FPREG_SET	FP_CONTEXT

/* defines */

#if (_BYTE_ORDER == _LITTLE_ENDIAN)
# define  HREG  1
# define  LREG  0
#else   /* _BYTE_ORDER != _LITTLE_ENDIAN */
# define  HREG  0
# define  LREG  1
#endif  /* _BYTE_ORDER == _LITTLE_ENDIAN */

/* typedefs */

typedef union
    {
    double d64;
    UINT32 u32[2];
    } FPP_UNION64D;


/* possible FPU error instructions */

#define FPE_MASK_2REG	0xf00f
#define FPE_INSN_FADD	0xf000		/* fadd */
#define FPE_INSN_FSUB	0xf001		/* fsub */
#define FPE_INSN_FMUL	0xf002		/* fmul */
#define FPE_INSN_FDIV	0xf003		/* fdiv */
#define FPE_INSN_FMAC	0xf00e		/* fmac - multiply and accumulate */

#define FPE_MASK_1REG	0xf0ff
#define FPE_INSN_FSQRT	0xf06d		/* fsqrt */
#define FPE_INSN_FCNVSD	0xf0ad		/* fcnvsd - convert single to double */
#define FPE_INSN_FCNVDS	0xf0bd		/* fcnvds - convert double to single */

/* variable declarations */

extern REG_INDEX fpRegName[];		/* f-point data register table */
extern REG_INDEX fpCtlRegName[];	/* f-point control register table */
extern WIND_TCB *pFppTaskIdPrevious;	/* task id for deferred exceptions */
extern FUNCPTR	 fppCreateHookRtn;	/* arch dependent create hook routine */
extern FUNCPTR	 fppDisplayHookRtn;	/* arch dependent display routine */


/* function declarations */

extern void	fppArchInit (void);
extern void	fppArchTaskCreateInit (FP_CONTEXT *pFpContext);
extern int	fppFpulGet (void);
extern void	fppFpulSet (int value);
extern int	fppFpscrGet (void);
extern void	fppFpscrSet (int value);
extern STATUS	fppProbeSup (void);
extern void	fppProbeTrap (void);
extern STATUS	fppExcHandle (ESFSH *pEsf, REG_SET *pRegs);
extern STATUS	fppRegGet (int regnum, UINT32 *p, int sz);
extern STATUS	fppRegSet (int regnum, UINT32 *p, int sz);

#endif	/* _ASMLANGUAGE */

#ifdef __cplusplus
}
#endif

#endif /* __INCfppShLibh */
